﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebHttpApi.WebHttpApi.Core
{
    /// <summary>
    /// TySign 的摘要说明：第三方平台数据接入签名类
    /// </summary>
    public class TySign
    {
        #region 签名:
        public static string Sign(string str_json)
        {
            string str_sign = "";

            str_sign = WebSdkCore.GetMD5String(str_json);
            return str_sign;
        }
        #endregion

        #region 推送数据签名验证
        //JSON组合字符串：用作签名
        public static string str_json(JObject json_post)
        {
            string str_result = "";
            JObject new_post = null;

            string str_post = SortJson(json_post, new_post);
            JObject new_json_post = (JObject)JsonConvert.DeserializeObject(str_post);

            foreach (JToken child in new_json_post.Children())
            {
                var temp = child as JProperty;

                if (temp.Name != "Timestamp" && temp.Name != "Secret" && temp.Name != "Sign")
                {
                    if (str_result == "")
                    {
                        str_result += temp.Name + "=" + temp.Value;
                    }
                    else
                    {
                        str_result += "&" + temp.Name + "=" + temp.Value;
                    }
                }
            }

            string str_timestamp = "";
            string str_Secret = "";
            str_timestamp = json_post["Timestamp"].ToString();
            str_Secret = json_post["Secret"].ToString();

            str_result += "&" + "Timestamp=" + str_timestamp;
            str_result += "&" + "Secret=" + str_Secret;

            return str_result;
        }
        #endregion

        #region 正序 JSON
        //  <summary>JSON格式化重新排序</summary>
        //  <param name="jobj">原始JSON JToken.Parse(string json);</param>
        //  <param name="obj">初始值Null</param>
        //  <returns></returns>        
        public static string SortJson(JToken jobj, JToken obj)
        {
            if (obj == null)
            {
                obj = new JObject();
            }
            List<JToken> list = jobj.ToList<JToken>();
            if (jobj.Type == JTokenType.Object)//非数组
            {
                List<string> listsort = new List<string>();
                foreach (var item in list)
                {
                    string name = JProperty.Load(item.CreateReader()).Name;
                    listsort.Add(name);
                }
                listsort.Sort();
                List<JToken> listTemp = new List<JToken>();
                foreach (var item in listsort)
                {
                    listTemp.Add(list.Where(p => JProperty.Load(p.CreateReader()).Name == item).FirstOrDefault());
                }
                list = listTemp;

                foreach (var item in list)
                {
                    JProperty jp = JProperty.Load(item.CreateReader());
                    if (item.First.Type == JTokenType.Object)
                    {
                        JObject sub = new JObject();
                        (obj as JObject).Add(jp.Name, sub);
                        SortJson(item.First, sub);
                    }
                    else if (item.First.Type == JTokenType.Array)
                    {
                        JArray arr = new JArray();
                        if (obj.Type == JTokenType.Object)
                        {
                            (obj as JObject).Add(jp.Name, arr);
                        }
                        else if (obj.Type == JTokenType.Array)
                        {
                            (obj as JArray).Add(arr);
                        }
                        SortJson(item.First, arr);
                    }
                    else if (item.First.Type != JTokenType.Object && item.First.Type != JTokenType.Array)
                    {
                        (obj as JObject).Add(jp.Name, item.First);
                    }
                }
            }
            else if (jobj.Type == JTokenType.Array)//数组
            {
                foreach (var item in list)
                {
                    List<JToken> listToken = item.ToList<JToken>();
                    List<string> listsort = new List<string>();
                    foreach (var im in listToken)
                    {
                        string name = JProperty.Load(im.CreateReader()).Name;
                        listsort.Add(name);
                    }
                    listsort.Sort();
                    List<JToken> listTemp = new List<JToken>();
                    foreach (var im2 in listsort)
                    {
                        listTemp.Add(listToken.Where(p => JProperty.Load(p.CreateReader()).Name == im2).FirstOrDefault());
                    }
                    list = listTemp;
                    listToken = list;
                    JObject item_obj = new JObject();
                    foreach (var token in listToken)
                    {
                        JProperty jp = JProperty.Load(token.CreateReader());
                        if (token.First.Type == JTokenType.Object)
                        {
                            JObject sub = new JObject();
                            (obj as JObject).Add(jp.Name, sub);
                            SortJson(token.First, sub);
                        }
                        else if (token.First.Type == JTokenType.Array)
                        {
                            JArray arr = new JArray();
                            if (obj.Type == JTokenType.Object)
                            {
                                (obj as JObject).Add(jp.Name, arr);
                            }
                            else if (obj.Type == JTokenType.Array)
                            {
                                (obj as JArray).Add(arr);
                            }
                            SortJson(token.First, arr);
                        }
                        else if (item.First.Type != JTokenType.Object && item.First.Type != JTokenType.Array)
                        {
                            if (obj.Type == JTokenType.Object)
                            {
                                (obj as JObject).Add(jp.Name, token.First);
                            }
                            else if (obj.Type == JTokenType.Array)
                            {
                                item_obj.Add(jp.Name, token.First);
                            }
                        }
                    }
                    if (obj.Type == JTokenType.Array)
                    {
                        (obj as JArray).Add(item_obj);
                    }
                }
            }
            string ret = obj.ToString(Formatting.None);
            return ret;
        }
        #endregion
    }
}